package com.gitee.openviducn.inspector.config;

import com.gitee.openviducn.inspector.common.BizException;
import com.gitee.openviducn.inspector.common.ResponseError;
import com.gitee.openviducn.inspector.common.ResponseResult;
import com.gitee.openviducn.inspector.constant.SymbolConstant;
import io.openvidu.java.client.OpenViduHttpException;
import io.openvidu.java.client.OpenViduJavaClientException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 全局异常管理
 * @Author: https://gitee.com/wesleyOne
 * @Date: 02.23 2020
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ResponseResult apiArgNotValidErrorHandle(HttpServletRequest request, Exception e) {
        StringBuilder message = new StringBuilder();
        if (e instanceof MethodArgumentNotValidException) {
            List<ObjectError> allErrors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
            if (CollectionUtils.isNotEmpty(allErrors)) {
                allErrors.forEach(err -> message.append(err.getDefaultMessage()).append(SymbolConstant.PIPE));
            }
        }
        return ResponseResult.error(ResponseError.PARAM_ERR.getCode(), message.toString(),request.getRequestURI());
    }

    @ExceptionHandler(value = {OpenViduJavaClientException.class, OpenViduHttpException.class})
    public ResponseResult openviduErrorHandle(HttpServletRequest request, Exception e) {
        String path = request.getRequestURI();
        if (e instanceof OpenViduJavaClientException) {
            log.error("OpenVidu客户端操作异常",e);
            return ResponseResult.error(ResponseError.OPENVIDU_CLIENT_ERR,e.getMessage(),path);
        } else if (e instanceof OpenViduHttpException) {
            log.error("OpenVidu请求异常",e);
            return ResponseResult.error(ResponseError.OPENVIDU_HTTP_ERR,e.getMessage(),path);
        } else {
            log.error("OpenVidu操作异常",e);
            return ResponseResult.error(ResponseError.SYSTEM_ERR,"OpenVidu操作异常",path);
        }
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseResult illegalArgumentHandler(HttpServletRequest request, Exception e) {
        return logAndReturn(request, e, "请求参数异常",ResponseError.PARAM_ERR);
    }

    @ExceptionHandler(value={BizException.class})
    public ResponseResult bizHandler(HttpServletRequest request, Exception e) {
        BizException bizException = (BizException) e;
        return logAndReturn(request, e, "业务异常原因",bizException.getCode(), bizException.getMessage());
    }

    @ExceptionHandler(value={Exception.class})
    public ResponseResult elseHandler(HttpServletRequest request, Exception e) {
        return logAndReturn(request, e,"系统异常原因",ResponseError.SYSTEM_BUSY);
    }

    @ExceptionHandler(value={Throwable.class})
    public ResponseResult throwableHandler(HttpServletRequest request, Exception e) {
        return logAndReturn(request, e, "严重系统异常原因",ResponseError.SYSTEM_ERR);
    }

    private ResponseResult logAndReturn(HttpServletRequest request, Exception e, String logHeader, ResponseError responseError) {
        return logAndReturn(request, e, logHeader, responseError.getCode(), responseError.getMsg());
    }

    private ResponseResult logAndReturn(HttpServletRequest request, Exception e, String logHeader, String code, String message) {
        log.error("{}-{},path:{}", message, code, request.getRequestURI(), e);
        return ResponseResult.error(code, message,request.getRequestURI());
    }

}


